package com.github.wxiaoqi.security.crm.core.biz;

import java.math.BigDecimal;
import java.text.Bidi;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.wxiaoqi.security.auth.common.util.SnowFlake;
import com.github.wxiaoqi.security.common.crm.request.RefundFreezeRequest;
import com.github.wxiaoqi.security.common.crm.request.RefundUnFreezeRequest;
import com.github.wxiaoqi.security.common.crm.request.WithdrawApplyRequest;
import com.github.wxiaoqi.security.common.crm.request.WithdrawUnFreAndOutAccountRequest;
import com.github.wxiaoqi.security.common.crm.request.WithdrawUnFreezeRequest;
import com.github.wxiaoqi.security.common.msg.ResponseCode;
import com.github.wxiaoqi.security.common.util.EntityUtils;
import com.github.wxiaoqi.security.common.util.MD5;
import com.github.wxiaoqi.security.crm.core.entity.FreezeJournal;
import com.github.wxiaoqi.security.crm.core.entity.MerchantAccount;
import com.github.wxiaoqi.security.crm.core.entity.MerchantAccountJournal;
import com.github.wxiaoqi.security.crm.core.entity.PersonalAccount;
import com.github.wxiaoqi.security.crm.core.entity.PersonalAccountJournal;
import com.github.wxiaoqi.security.crm.core.entity.PersonalBilling;
import com.github.wxiaoqi.security.crm.core.entity.UnfreezeJournal;
import com.github.wxiaoqi.security.crm.core.mapper.FreezeJournalMapper;
import com.github.wxiaoqi.security.crm.core.mapper.MerchantAccountJournalMapper;
import com.github.wxiaoqi.security.crm.core.mapper.MerchantAccountMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalAccountJournalMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalAccountMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalBillingMapper;
import com.github.wxiaoqi.security.crm.core.mapper.UnfreezeJournalMapper;

import lombok.extern.slf4j.Slf4j;

/**
 * 提现相关的操作接口--个人账户
 */
@Slf4j
@Transactional(rollbackFor = Exception.class)
@Service
public class WithdrawCommonBiz {
	@Autowired
	private PersonalBillingMapper personalBillingMapper;
	@Autowired
	private PersonalAccountMapper personalAccountMapper;
	@Autowired
	private PersonalAccountJournalMapper personalAccountJournalMapper;
	@Autowired
	private FreezeJournalMapper freezeJournalMapper;
	@Autowired
	private UnfreezeJournalMapper unfreezeJournalMapper;
	@Value("${bountyHunter.balanceSaltValue}")
	private String balanceSaltValue;
	/**
	 * 个人发起提现申请接口
	 *  1.个人账户余额减少，冻结金额增加。
	 *  2.新增冻结流水记录、个人账单记录。
	 */
	public Map<String, Object> withdrawApply(WithdrawApplyRequest withdrawApplyRequest) {
		log.info("个人发起提现申请接口-请求参数：{}" + EntityUtils.beanToMap(withdrawApplyRequest));
		Map<String, Object> response = new HashMap<String, Object>();
		/**
		 * --
		 * 获取个人账户余额A	
		 * 本次提现金额 C  若C>A
		 * 则用户不能本次提现
		 */
		PersonalAccount queryPerAccountparam=new PersonalAccount();
		queryPerAccountparam.setPlatformId(withdrawApplyRequest.getPlatformId());
		queryPerAccountparam.setPersonalId(withdrawApplyRequest.getPersonalId());
		queryPerAccountparam.setAccountType(withdrawApplyRequest.getAccountType());
		PersonalAccount personalAccount=personalAccountMapper.selectOne(queryPerAccountparam);
		if(null!=personalAccount){
		/***
		 * 校验个人账户余额数据库中是否匹配，个人账户余额是否充足
		 * */
		try {
			if(!MD5.sign(personalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8").equals(personalAccount.getCheckSum())){
				response.put("code", ResponseCode.PER_ACC_BALANCE_NOT_MATE.getCode());
				response.put("msg", ResponseCode.PER_ACC_BALANCE_NOT_MATE.getMessage());
				log.info("个人发起提现申请接口 返回参数。。。。。。{}", response);
				return response;
			}
			if(personalAccount.getAccountBalance().compareTo(new BigDecimal(withdrawApplyRequest.getWithDrawAmt()))<0){//商户账户余额不足
				response.put("code", ResponseCode.MER_ACC_BALANCE_NOT_ENOUGH.getCode());
				response.put("msg", ResponseCode.MER_ACC_BALANCE_NOT_ENOUGH.getMessage());
				log.info("个人发起提现申请接口 返回参数。。。。。。{}", response);
				return response;
			}
			/**
			 * 修改个人账户余额 和冻结余额
			 * */
			personalAccount.setAccountBalance(personalAccount.getAccountBalance().subtract(new BigDecimal(withdrawApplyRequest.getWithDrawAmt())));
			personalAccount.setFreezeBalance(personalAccount.getFreezeBalance().add(new BigDecimal(withdrawApplyRequest.getWithDrawAmt())));
			personalAccount.setUpdateTime(new Date());
			personalAccountMapper.updateByPrimaryKeySelective(personalAccount);
			/**
			 * 新增冻结流水记录和个人账单申请提现记录
			 * */
			FreezeJournal freezeJournal=new FreezeJournal();
			String freezeId =String.valueOf(SnowFlake.getId());
			freezeJournal.setJournalId(freezeId);
			freezeJournal.setPlatformId(withdrawApplyRequest.getPlatformId());
			freezeJournal.setCustomerType(withdrawApplyRequest.getCustomerType());
			freezeJournal.setCustomerNo(withdrawApplyRequest.getPersonalId());
			freezeJournal.setTradeType("03");//交易类型（支付:01，退款:02，提现:03，充值:04）
			freezeJournal.setOrderNo(withdrawApplyRequest.getWithdrawOrderNo());
			freezeJournal.setFreezeBalance(new BigDecimal(withdrawApplyRequest.getWithDrawAmt()));
			freezeJournal.setStatus("1");//冻结状态    1：已冻结  2：部分解冻  3：已解冻
			freezeJournal.setCreateTime(new Date());
			freezeJournalMapper.insertSelective(freezeJournal);
			PersonalBilling billing = new PersonalBilling();
			billing.setBillId(String.valueOf(SnowFlake.getId()));
			billing.setPlatformId(withdrawApplyRequest.getPlatformId());
			billing.setOrderNo(withdrawApplyRequest.getWithdrawOrderNo());
			//billing.setBillType("");
			billing.setInOutFlag("2");
			billing.setTradeAmt(new BigDecimal(withdrawApplyRequest.getWithDrawAmt()));
			billing.setSellerType(withdrawApplyRequest.getCustomerType());
			billing.setProduceInfo(withdrawApplyRequest.getProduceInfo());
			billing.setPayWay(withdrawApplyRequest.getPayWay());
			billing.setCreateTime(new Date());
			billing.setTradeType("03");//交易类型（支付:01，退款:02，提现:03，充值:04）
			billing.setStatus("04");//账单状态（付款成功 00 ，充值成功 01 ，退款申请成功02，退款成功03， 提现申请成功04 ，提现处理成功 05 ）
			personalBillingMapper.insertSelective(billing);
			response.put("freezeId", freezeId);
			response.put("code", ResponseCode.OK.getCode());
			response.put("msg", ResponseCode.OK.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			log.info("个人发起提现申请接口 报错--"+e.getMessage());
			response.put("code", ResponseCode.ABNORMAL_FIELDS.getCode());
			response.put("msg", ResponseCode.ABNORMAL_FIELDS.getMessage());
			return response;
		}
		}else{
			log.info("个人发起提现申请接口--个人账户不存在");
			response.put("code", ResponseCode.PER_ACC_NOTEXIST.getCode());
			response.put("msg", ResponseCode.PER_ACC_NOTEXIST.getMessage());
			return response;
		}
		return response;
	}
	/**
	 * 提现失败时 解冻资金的接口 
	 * 1.个人账户余额账户增加，冻结金额扣除。新增解冻记录。
	 * 2.个人账单提现记录重置为‘提现失败’
	 */
	public Map<String, Object> withdrawUnFreeze(WithdrawUnFreezeRequest withdrawUnFreezeRequest) {
		log.info("提现失败时 解冻资金的接口 -请求参数：{}" + EntityUtils.beanToMap(withdrawUnFreezeRequest));
		Map<String, Object> response = new HashMap<String, Object>();
		/**
		 * 根据冻结流水号查询是否被解冻
		 * */
		UnfreezeJournal queryUnfreezeJournal = new UnfreezeJournal();
		queryUnfreezeJournal.setFreezeId(withdrawUnFreezeRequest.getFreezeId());
		queryUnfreezeJournal.setOrderNo(withdrawUnFreezeRequest.getWithdrawOrderNo());
		UnfreezeJournal unfreezeJournal=unfreezeJournalMapper.selectOne(queryUnfreezeJournal);
		if(null!=unfreezeJournal){
			log.info("提现失败时 解冻资金的接口--冻结资金已解冻");
			response.put("code", ResponseCode.UNFREEZE_IS_EXIST.getCode());
			response.put("msg", ResponseCode.UNFREEZE_IS_EXIST.getMessage());
			return response;
		}
		try {
			PersonalAccount queryPerAccountparam=new PersonalAccount();
			queryPerAccountparam.setPlatformId(withdrawUnFreezeRequest.getPlatformId());
			queryPerAccountparam.setPersonalId(withdrawUnFreezeRequest.getPersonalId());
			queryPerAccountparam.setAccountType(withdrawUnFreezeRequest.getAccountType());
			PersonalAccount personalAccount=personalAccountMapper.selectOne(queryPerAccountparam);
			if(null!=personalAccount){
				//校验余额加密值的校验
				if(!MD5.sign(personalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8").equals(personalAccount.getCheckSum())){
					response.put("code", ResponseCode.PER_ACC_BALANCE_NOT_MATE.getCode());
					response.put("msg", ResponseCode.PER_ACC_BALANCE_NOT_MATE.getMessage());
					log.info("提现失败时 解冻资金的接口 返回参数。。。。。。{}", response);
					return response;
				}
				personalAccount.setAccountBalance(personalAccount.getAccountBalance().add(new BigDecimal(withdrawUnFreezeRequest.getWithDrawAmt())));
				personalAccount.setFreezeBalance(personalAccount.getFreezeBalance().subtract(new BigDecimal(withdrawUnFreezeRequest.getWithDrawAmt())));
				personalAccountMapper.updateByPrimaryKeySelective(personalAccount);
			}else{
				log.info("提现失败时 解冻资金的接口--个人账户不存在");
				response.put("code", ResponseCode.MER_ACC_NOTEXIST.getCode());
				response.put("msg", ResponseCode.MER_ACC_NOTEXIST.getMessage());
				return response;
			}
			/***
			 * 新增解冻流水记录和个人账单增加退款申请改成失败
			 * */
			queryUnfreezeJournal.setJournalId(String.valueOf(SnowFlake.getId()));
			queryUnfreezeJournal.setTradeType("03");//交易类型（支付:01，退款:02，提现:03，充值:04）
			queryUnfreezeJournal.setUnfreezeBalance(new BigDecimal(withdrawUnFreezeRequest.getWithDrawAmt()));
			queryUnfreezeJournal.setCreateTime(new Date());
			unfreezeJournalMapper.insertSelective(queryUnfreezeJournal);
			PersonalBilling billing = new PersonalBilling();
			billing.setPlatformId(withdrawUnFreezeRequest.getPlatformId());
			billing.setOrderNo(withdrawUnFreezeRequest.getWithdrawOrderNo());
			billing.setPersonalId(withdrawUnFreezeRequest.getPersonalId());
			billing.setTradeType("02");
			PersonalBilling perBill=personalBillingMapper.selectOne(billing);
			if(null!=perBill){
				perBill.setStatus("07");//提现失败
				personalBillingMapper.updateByPrimaryKeySelective(perBill);
				response.put("code", ResponseCode.OK.getCode());
				response.put("msg", ResponseCode.OK.getMessage());
			}else{
				log.info("提现失败时 解冻资金的接口--个人提现账单不存在");
				response.put("code", ResponseCode.PER_REFONDBILL_NOT_EXIST.getCode());
				response.put("msg", ResponseCode.PER_REFONDBILL_NOT_EXIST.getMessage());
				return response;
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.info("提现失败时 解冻资金的接口报错--"+e.getMessage());
			response.put("code", ResponseCode.ABNORMAL_FIELDS.getCode());
			response.put("msg", ResponseCode.ABNORMAL_FIELDS.getMessage());
			return response;
		}
		return response;
		
	}
	/**
	 * 
	 * 提现成功后解冻并出账接口
	 * 1.个人账户冻结余额扣除，新增解冻流水记录。
	 * 2.个人账户流水增加一条记录
	 * 3.个人账单提现记录状态重置为‘提现成功’
	 * */
	public Map<String, Object> withdrawUnFreAndOutAccount(WithdrawUnFreAndOutAccountRequest withdrawUnFreAndOutAccountRequest) {
		log.info("提现成功后解冻并出账接口  -请求参数：{}" + EntityUtils.beanToMap(withdrawUnFreAndOutAccountRequest));
		Map<String, Object> response = new HashMap<String, Object>();
		/**
		 * 根据冻结流水号查询是否被解冻
		 * */
		UnfreezeJournal queryUnfreezeJournal = new UnfreezeJournal();
		queryUnfreezeJournal.setFreezeId(withdrawUnFreAndOutAccountRequest.getFreezeId());
		queryUnfreezeJournal.setOrderNo(withdrawUnFreAndOutAccountRequest.getWithdrawOrderNo());
		UnfreezeJournal unfreezeJournal=unfreezeJournalMapper.selectOne(queryUnfreezeJournal);
		if(null!=unfreezeJournal){
			log.info("提现成功后解冻并出账接口--冻结资金已解冻");
			response.put("code", ResponseCode.UNFREEZE_IS_EXIST.getCode());
			response.put("msg", ResponseCode.UNFREEZE_IS_EXIST.getMessage());
			return response;
		}
		try {
			PersonalAccount queryPerAccountparam=new PersonalAccount();
			queryPerAccountparam.setPlatformId(withdrawUnFreAndOutAccountRequest.getPlatformId());
			queryPerAccountparam.setPersonalId(withdrawUnFreAndOutAccountRequest.getPersonalId());
			queryPerAccountparam.setAccountType(withdrawUnFreAndOutAccountRequest.getAccountType());
			PersonalAccount personalAccount=personalAccountMapper.selectOne(queryPerAccountparam);
			if(null!=personalAccount){
				personalAccount.setFreezeBalance(personalAccount.getFreezeBalance().subtract(new BigDecimal(withdrawUnFreAndOutAccountRequest.getWithDrawAmt())));
				personalAccountMapper.updateByPrimaryKeySelective(personalAccount);
			}else{
				log.info("提现成功后解冻并出账接口--个人账户不存在");
				response.put("code", ResponseCode.MER_ACC_NOTEXIST.getCode());
				response.put("msg", ResponseCode.MER_ACC_NOTEXIST.getMessage());
				return response;
			}
			/***
			 * 新增解冻流水记录和个人账号流水记录
			 * */
			queryUnfreezeJournal.setJournalId(String.valueOf(SnowFlake.getId()));
			queryUnfreezeJournal.setTradeType("03");//交易类型（支付:01，退款:02，提现:03，充值:04）
			queryUnfreezeJournal.setUnfreezeBalance(new BigDecimal(withdrawUnFreAndOutAccountRequest.getWithDrawAmt()));
			queryUnfreezeJournal.setCreateTime(new Date());
			unfreezeJournalMapper.insertSelective(queryUnfreezeJournal);
			PersonalAccountJournal personalAccountJournal=new PersonalAccountJournal();
			personalAccountJournal.setJournalId(String.valueOf(SnowFlake.getId()));
			personalAccountJournal.setPlatformId(withdrawUnFreAndOutAccountRequest.getPlatformId());
			personalAccountJournal.setPersonalId(withdrawUnFreAndOutAccountRequest.getPersonalId());
			personalAccountJournal.setAccountId(personalAccount.getAccountId());
			personalAccountJournal.setAccountType(personalAccount.getAccountType());
			personalAccountJournal.setOrderNo(withdrawUnFreAndOutAccountRequest.getWithdrawOrderNo());
			personalAccountJournal.setInOutFlag("2");//来往标志  1：入账   2：出账
			personalAccountJournal.setTradeAmt(new BigDecimal(withdrawUnFreAndOutAccountRequest.getWithDrawAmt()));
			personalAccountJournal.setTradeType("03");//交易类型（支付:01，退款:02，提现:03，充值:04）
			personalAccountJournal.setCreateTime(new Date());
			personalAccountJournalMapper.insertSelective(personalAccountJournal);
			PersonalBilling billing = new PersonalBilling();
			billing.setPlatformId(withdrawUnFreAndOutAccountRequest.getPlatformId());
			billing.setOrderNo(withdrawUnFreAndOutAccountRequest.getWithdrawOrderNo());
			billing.setPersonalId(withdrawUnFreAndOutAccountRequest.getPersonalId());
			billing.setTradeType("04");//提现申请中的
			PersonalBilling perBill=personalBillingMapper.selectOne(billing);
			if(null!=perBill){
				perBill.setStatus("05");//提现成功
				personalBillingMapper.updateByPrimaryKeySelective(perBill);
				response.put("code", ResponseCode.OK.getCode());
				response.put("msg", ResponseCode.OK.getMessage());
			}else{
				log.info("提现成功后解冻并出账接口--个人提现账单不存在");
				response.put("code", ResponseCode.PER_REFONDBILL_NOT_EXIST.getCode());
				response.put("msg", ResponseCode.PER_REFONDBILL_NOT_EXIST.getMessage());
				return response;
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.info("提现成功后解冻并出账接口--"+e.getMessage());
			response.put("code", ResponseCode.ABNORMAL_FIELDS.getCode());
			response.put("msg", ResponseCode.ABNORMAL_FIELDS.getMessage());
			return response;
		}
		return response;
		
	}
}
